Popular Searches
Popular Course Categories
Popular Courses

Managing Input Fields Using TextInput

Managing Input Fields Using TextInput

Forms, Validation, and User Input Handling

Managing Input Fields Using TextInput in React Native

Course: React Native Training

Topic: Managing Input Fields Using TextInput

Course Link: React Native Training at JustAcademy

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction to TextInput in React Native

TextInput is a core React Native component that allows users to enter and edit text using the device keyboard. It is commonly used to build login screens, registration forms, search boxes, contact forms, feedback forms, messaging applications, and other interactive mobile interfaces.

React Native provides properties and event handlers that help developers control the entered text, choose suitable keyboard layouts, validate user input, handle focus, submit forms, and improve the overall user experience.

1.1 What Is TextInput?

TextInput is a component that receives text from users and allows the application to respond to changes in that text. It supports single-line and multiline input, placeholders, secure password entry, keyboard configuration, and several input events.

1.2 Why Is TextInput Important?

  • Collects information directly from users.
  • Supports login and registration workflows.
  • Allows users to search for content.
  • Accepts email addresses, phone numbers, names, passwords, and messages.
  • Provides events for responding to typing, focus changes, and submission.
  • Supports input validation and error messages.
  • Helps build reusable and accessible form components.

1.3 Common Applications

Application Example Purpose
Login screen Email and password Collects login credentials.
Registration form Name, email, phone Creates a user profile.
Search screen Search keyword Finds relevant content.
Messaging app Message text Composes messages.
Feedback form Comments Collects longer responses.
Profile screen Display name Updates user information.

2. Learning Objectives

After completing this topic, learners should be able to:

  • Understand the purpose and working of React Native's TextInput component.
  • Create controlled input fields using React state.
  • Handle user input with the onChangeText event.
  • Configure keyboard types, placeholders, and capitalization.
  • Build password and multiline text fields.
  • Validate user input and display error messages.
  • Handle focus, blur, and form submission events.
  • Manage multiple input fields in a form.
  • Improve usability, accessibility, and security.
  • Build a functional form using reusable input components.

3. Setting Up TextInput

3.1 Importing TextInput

To use TextInput, import it from the react-native package along with the other components needed by your screen.

import React, { useState } from 'react';
import {
  View,
  Text,
  TextInput,
  StyleSheet
} from 'react-native';

3.2 Creating a Basic Input Field

The following example creates a simple field that accepts a user's name.

import React, { useState } from 'react';
import { View, Text, TextInput } from 'react-native';

export default function NameInput() {
  const [name, setName] = useState('');

  return (
    <View>
      <Text>Enter your name</Text>
      <TextInput
        placeholder="Your name"
        value={name}
        onChangeText={setName}
      />
      <Text>Entered name: {name}</Text>
    </View>
  );
}

Explanation:

  • useState('') creates state for the entered name.
  • placeholder displays a hint when the field is empty.
  • value={name} connects the displayed text to state.
  • onChangeText={setName} updates state whenever the user types.
  • The final Text component displays the current value.

3.3 Styling the Input Field

TextInput can be styled using React Native's style prop. Common styling properties include height, padding, border width, border color, font size, and border radius.

const styles = StyleSheet.create({
  input: {
    height: 48,
    borderWidth: 1,
    borderColor: '#999999',
    borderRadius: 8,
    paddingHorizontal: 12,
    fontSize: 16,
    marginVertical: 8
  }
});

Apply the style using style={styles.input} on the TextInput component. React Native styles use JavaScript objects rather than CSS files.

4. Understanding Controlled and Uncontrolled Inputs

4.1 Controlled Input

A controlled input receives its value from React state. The value prop determines the displayed text, and onChangeText updates that state.

const [email, setEmail] = useState('');

<TextInput
  value={email}
  onChangeText={setEmail}
  placeholder="Enter email"
/>

Advantages:

  • Provides predictable input behavior.
  • Makes validation easier.
  • Allows values to be cleared or changed programmatically.
  • Supports conditional UI and form submission.
  • Makes it straightforward to manage multiple fields.

4.2 Uncontrolled Input

An uncontrolled input can use defaultValue to specify its initial text without keeping every change synchronized with a state variable.

<TextInput
  defaultValue="Welcome"
  placeholder="Enter text"
/>

This approach may be useful for simple fields that do not need to be read or validated continuously. If an application needs reliable access to the latest input, controlled state is generally easier to manage.

4.3 Controlled vs. Uncontrolled Inputs

Feature Controlled Uncontrolled
Value management Managed using React state Primarily managed by the input component
Initial value Usually provided through value Usually provided through defaultValue
Validation Easy to coordinate with state Requires a suitable way to access the current value
Programmatic updates Straightforward through state Less direct
Typical use Forms, login screens, search interfaces Simple fields that need little application control

5. Managing Input with useState

5.1 Introduction to useState

The useState Hook stores information that changes during a component's lifetime. When a state value changes, React renders the component again so that the UI reflects the updated value.

const [username, setUsername] = useState('');

Here, username contains the current value, while setUsername updates it.

5.2 Updating Input State

function UsernameField() {
  const [username, setUsername] = useState('');

  return (
    <TextInput
      value={username}
      onChangeText={(text) => setUsername(text)}
      placeholder="Username"
    />
  );
}

The onChangeText callback receives the updated text as a string. It does not require extracting the text from a browser-style event object.

5.3 Clearing an Input Field

function ClearableInput() {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        value={text}
        onChangeText={setText}
        placeholder="Type something"
      />
      <Text onPress={() => setText('')}>
        Clear input
      </Text>
    </View>
  );
}

This example demonstrates state-based clearing. In a production interface, use a button component for the clear action and give it a clear accessible label.

6. Important TextInput Props

Props control how a field looks, accepts text, interacts with the keyboard, and responds to user actions.

Prop Purpose Example
value Sets the current controlled value. value={email}
defaultValue Sets an initial value. defaultValue="Guest"
onChangeText Runs when the text changes. onChangeText={setEmail}
placeholder Shows a hint when the field is empty. placeholder="Enter email"
placeholderTextColor Changes the placeholder color. placeholderTextColor="#777"
keyboardType Chooses a suitable keyboard layout. keyboardType="email-address"
secureTextEntry Obscures sensitive text such as a password. secureTextEntry={true}
multiline Allows text to span multiple lines. multiline={true}
maxLength Limits the number of entered characters. maxLength={50}
autoCapitalize Controls automatic capitalization. autoCapitalize="none"
autoCorrect Controls text auto-correction. autoCorrect={false}
editable Controls whether text can be edited. editable={false}
autoFocus Requests focus when the component mounts. autoFocus={true}
returnKeyType Customizes the keyboard's return key. returnKeyType="done"
onSubmitEditing Handles the keyboard submission action. onSubmitEditing={handleSubmit}
onFocus Runs when the field receives focus. onFocus={handleFocus}
onBlur Runs when the field loses focus. onBlur={handleBlur}

7. Choosing the Correct Keyboard Type

The keyboardType prop helps display a keyboard that suits the expected data. Choosing an appropriate keyboard reduces unnecessary typing and improves usability.

Keyboard Type Recommended Use
default General text input.
email-address Email addresses.
numeric Numeric input.
number-pad Number entry on supported platforms.
decimal-pad Numbers containing decimal values.
phone-pad Telephone numbers.
url Website addresses.
search Search terms.

7.1 Example: Email Input

<TextInput
  value={email}
  onChangeText={setEmail}
  placeholder="[email protected]"
  keyboardType="email-address"
  autoCapitalize="none"
  autoCorrect={false}
/>

7.2 Example: Phone Number Input

<TextInput
  value={phone}
  onChangeText={setPhone}
  placeholder="Enter phone number"
  keyboardType="phone-pad"
  maxLength={15}
/>

A keyboard type only influences the keyboard layout. It does not guarantee that the entered value is valid. Validate phone numbers, numeric values, and other structured input separately.

8. Creating Password Fields

Password fields are used on login, registration, and password-reset screens. The secureTextEntry prop obscures the text entered into a single-line field.

function PasswordInput() {
  const [password, setPassword] = useState('');

  return (
    <TextInput
      value={password}
      onChangeText={setPassword}
      placeholder="Enter password"
      secureTextEntry={true}
      autoCapitalize="none"
      autoCorrect={false}
    />
  );
}

8.1 Password Field Best Practices

  • Use secure text entry when appropriate.
  • Do not print passwords in logs or error messages.
  • Do not store passwords in ordinary persistent storage unnecessarily.
  • Validate password requirements without exposing the password.
  • Use HTTPS when sending credentials to a server.
  • Keep password handling separate from presentation logic when building larger forms.
  • Consider a clearly labeled show/hide password control if the design requires it.

Obscuring text is a display feature, not a complete security solution. Authentication, secure network communication, and credential storage require additional safeguards.

9. Handling Multiline Input

Use multiline={true} when the user needs to enter longer text, such as a message, description, review, or feedback comment.

function FeedbackInput() {
  const [feedback, setFeedback] = useState('');

  return (
    <View>
      <Text>Your feedback</Text>
      <TextInput
        value={feedback}
        onChangeText={setFeedback}
        placeholder="Write your feedback here"
        multiline={true}
        numberOfLines={4}
        maxLength={500}
        textAlignVertical="top"
        style={{
          minHeight: 120,
          borderWidth: 1,
          borderColor: '#999',
          borderRadius: 8,
          padding: 12
        }}
      />
      <Text>{feedback.length}/500 characters</Text>
    </View>
  );
}

9.1 Important Multiline Considerations

  • Use multiline={true} to allow line breaks.
  • Use textAlignVertical="top" for consistent top alignment where supported.
  • Use a suitable minimum height and padding.
  • Set a reasonable character limit when required.
  • Test the field on both Android and iOS.
  • Do not assume numberOfLines behaves identically across all platforms and React Native versions.

10. Handling TextInput Events

10.1 onChangeText

onChangeText is one of the most frequently used TextInput props. It receives the new text value whenever the input changes.

<TextInput
  value={name}
  onChangeText={(text) => setName(text)}
  placeholder="Enter your name"
/>

10.2 onFocus

The onFocus event runs when the user selects or focuses the field. It can be used to highlight the field or update interface state.

<TextInput
  value={name}
  onChangeText={setName}
  onFocus={() => console.log('Input focused')}
/>

10.3 onBlur

The onBlur event runs when the field loses focus. It is useful for checking whether an entered value meets basic requirements after the user leaves the field.

<TextInput
  value={email}
  onChangeText={setEmail}
  onBlur={() => setEmailTouched(true)}
/>

10.4 onSubmitEditing

onSubmitEditing runs when the user activates the keyboard's submission key, subject to platform and keyboard behavior. It can submit a search query or move a form toward its next action.

<TextInput
  value={search}
  onChangeText={setSearch}
  placeholder="Search"
  returnKeyType="search"
  onSubmitEditing={() => performSearch(search)}
/>

Ensure that performSearch is defined in the component. For phone-pad keyboards, some submission events may behave differently across platforms.

10.5 Event Summary

Event When It Runs Typical Use
onChangeText Text changes. Update state and live feedback.
onFocus Field receives focus. Highlight active input.
onBlur Field loses focus. Trigger field-level validation.
onEndEditing Editing ends. Process the final edited value.
onSubmitEditing Keyboard submission action occurs. Submit a search or form.
onKeyPress A supported keyboard key is pressed. Special key interactions.
onSelectionChange Text selection changes. Respond to cursor or selection changes.

11. Managing Multiple Input Fields

Forms commonly contain several inputs, including a name, email address, phone number, and password. Each field needs a value and a way to update it.

11.1 Separate State Variables

const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');

<TextInput value={name} onChangeText={setName} placeholder="Name" />
<TextInput value={email} onChangeText={setEmail} placeholder="Email" />
<TextInput value={phone} onChangeText={setPhone} placeholder="Phone" />

This method is easy to understand and works well for small forms.

11.2 Grouping Form State in an Object

For a form with several fields, an object can keep related values together.

const [form, setForm] = useState({
  name: '',
  email: '',
  phone: ''
});

function updateField(field, value) {
  setForm(previous => ({
    ...previous,
    [field]: value
  }));
}

// Example fields
<TextInput
  value={form.name}
  onChangeText={(value) => updateField('name', value)}
  placeholder="Full name"
/>

<TextInput
  value={form.email}
  onChangeText={(value) => updateField('email', value)}
  placeholder="Email address"
  keyboardType="email-address"
  autoCapitalize="none"
/>

The spread operator preserves the other fields while updating only the selected property. This prevents a change to one field from accidentally removing the other form values.

12. Input Validation

Input validation checks whether the data entered by a user meets the application's requirements. Validation can occur while the user types, when the field loses focus, or when the user submits the form.

12.1 Why Validation Is Necessary

  • Prevents empty required fields from being submitted.
  • Helps identify incorrectly formatted email addresses.
  • Enforces character limits and other field requirements.
  • Provides useful feedback before a request is sent to the server.
  • Improves the reliability of information collected by the application.

12.2 Required Field Validation

const [name, setName] = useState('');
const [submitted, setSubmitted] = useState(false);

const nameError =
  submitted && name.trim().length === 0
    ? 'Name is required.'
    : '';

function handleSubmit() {
  setSubmitted(true);

  if (!name.trim()) {
    return;
  }

  // Continue with the valid form data.
}

12.3 Email Validation

function isValidEmail(value) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
}

const emailError =
  submitted && !isValidEmail(email)
    ? 'Enter a valid email address.'
    : '';

This regular expression provides a basic format check. It does not prove that an email address exists or that the user owns it. Important data should also be validated by the server.

12.4 Displaying Validation Errors

<TextInput
  value={email}
  onChangeText={setEmail}
  placeholder="Email address"
  keyboardType="email-address"
  autoCapitalize="none"
  accessibilityLabel="Email address"
/>
{emailError ? (
  <Text accessibilityLiveRegion="polite">
    {emailError}
  </Text>
) : null}

Keep error messages clear, associate them with the correct field, and avoid showing errors before the user has had a reasonable opportunity to enter data.

13. Building a Complete Registration Form

The following example combines several important concepts: controlled input fields, keyboard configuration, basic validation, character handling, and form submission.

import React, { useState } from 'react';
import {
  View,
  Text,
  TextInput,
  Pressable,
  StyleSheet
} from 'react-native';

export default function RegistrationForm() {
  const [form, setForm] = useState({
    name: '',
    email: '',
    password: ''
  });
  const [submitted, setSubmitted] = useState(false);
  const [successMessage, setSuccessMessage] = useState('');

  function updateField(field, value) {
    setForm(previous => ({
      ...previous,
      [field]: value
    }));
    setSuccessMessage('');
  }

  const nameError =
    submitted && !form.name.trim()
      ? 'Please enter your name.'
      : '';

  const emailError =
    submitted && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim())
      ? 'Please enter a valid email address.'
      : '';

  const passwordError =
    submitted && form.password.length < 8
      ? 'Password must contain at least 8 characters.'
      : '';

  function handleSubmit() {
    setSubmitted(true);
    setSuccessMessage('');

    const validName = form.name.trim().length > 0;
    const validEmail =
      /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim());
    const validPassword = form.password.length >= 8;

    if (!validName || !validEmail || !validPassword) {
      return;
    }

    // Send form data to your backend here.
    // Never log the password or expose it in UI messages.
    setSuccessMessage('Form validation completed successfully.');
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Create Account</Text>

      <Text style={styles.label}>Full Name</Text>
      <TextInput
        style={styles.input}
        value={form.name}
        onChangeText={(value) => updateField('name', value)}
        placeholder="Enter your name"
        autoCapitalize="words"
        autoCorrect={false}
        accessibilityLabel="Full name"
      />
      {nameError ? <Text style={styles.error}>{nameError}</Text> : null}

      <Text style={styles.label}>Email Address</Text>
      <TextInput
        style={styles.input}
        value={form.email}
        onChangeText={(value) => updateField('email', value)}
        placeholder="Enter your email"
        keyboardType="email-address"
        autoCapitalize="none"
        autoCorrect={false}
        accessibilityLabel="Email address"
      />
      {emailError ? <Text style={styles.error}>{emailError}</Text> : null}

      <Text style={styles.label}>Password</Text>
      <TextInput
        style={styles.input}
        value={form.password}
        onChangeText={(value) => updateField('password', value)}
        placeholder="At least 8 characters"
        secureTextEntry={true}
        autoCapitalize="none"
        autoCorrect={false}
        accessibilityLabel="Password"
      />
      {passwordError ? <Text style={styles.error}>{passwordError}</Text> : null}

      <Pressable
        style={styles.button}
        onPress={handleSubmit}
        accessibilityRole="button"
        accessibilityLabel="Submit registration form"
      >
        <Text style={styles.buttonText}>Register</Text>
      </Pressable>

      {successMessage ? (
        <Text accessibilityLiveRegion="polite">
          {successMessage}
        </Text>
      ) : null}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20
  },
  label: {
    fontSize: 16,
    marginBottom: 6
  },
  input: {
    minHeight: 48,
    borderWidth: 1,
    borderColor: '#999999',
    borderRadius: 8,
    paddingHorizontal: 12,
    marginBottom: 8
  },
  error: {
    marginBottom: 10
  },
  button: {
    padding: 14,
    borderRadius: 8,
    alignItems: 'center',
    marginTop: 12,
    backgroundColor: '#2457C5'
  },
  buttonText: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: 'bold'
  }
});

13.1 How the Example Works

  1. The form state object stores the name, email, and password.
  2. The updateField function changes the selected field while preserving the remaining values.
  3. The name validator checks whether the name contains non-whitespace characters.
  4. The email validator performs a basic email-format check.
  5. The password validator checks for a minimum of eight characters.
  6. The submitted state controls when validation errors are displayed.
  7. The submit handler stops when the entered values are invalid.
  8. When basic validation succeeds, the example displays a message. A real registration flow must send the data to a backend and handle the response.

14. Managing Focus and Keyboard Behavior

14.1 What Is Focus?

A field has focus when it is active and ready to receive text. Focus management is helpful when moving between form fields or directing the user to a field that needs attention.

14.2 Focusing an Input Programmatically

React Native exposes methods such as focus() and blur() on the TextInput instance. A ref can be used to call these methods.

import React, { useRef, useState } from 'react';
import { View, TextInput, Button } from 'react-native';

export default function FocusExample() {
  const inputRef = useRef(null);
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        ref={inputRef}
        value={text}
        onChangeText={setText}
        placeholder="Enter text"
      />
      <Button
        title="Focus input"
        onPress={() => inputRef.current?.focus()}
      />
      <Button
        title="Dismiss focus"
        onPress={() => inputRef.current?.blur()}
      />
    </View>
  );
}

14.3 Keyboard Configuration

  • Use returnKeyType="next" when the user should move to another field.
  • Use returnKeyType="done" for an appropriate final input action.
  • Use onSubmitEditing to handle keyboard submission.
  • Use autoFocus only when immediately focusing the field improves the experience.
  • Test how the keyboard affects the screen on small devices.

15. Reusable TextInput Components

In larger applications, creating a reusable input component reduces duplicated code and encourages consistent styling, labels, validation messages, and accessibility properties.

15.1 Creating a Reusable Input Component

import React from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';

export default function FormInput({
  label,
  value,
  onChangeText,
  placeholder,
  error,
  keyboardType = 'default',
  secureTextEntry = false
}) {
  return (
    <View style={styles.wrapper}>
      <Text style={styles.label}>{label}</Text>
      <TextInput
        style={styles.input}
        value={value}
        onChangeText={onChangeText}
        placeholder={placeholder}
        keyboardType={keyboardType}
        secureTextEntry={secureTextEntry}
        autoCapitalize={keyboardType === 'email-address' ? 'none' : 'sentences'}
        accessibilityLabel={label}
      />
      {error ? <Text style={styles.error}>{error}</Text> : null}
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    marginBottom: 16
  },
  label: {
    fontSize: 15,
    marginBottom: 6
  },
  input: {
    minHeight: 48,
    borderWidth: 1,
    borderColor: '#999999',
    borderRadius: 8,
    paddingHorizontal: 12
  },
  error: {
    marginTop: 4
  }
});

15.2 Using the Reusable Component

<FormInput
  label="Email Address"
  value={email}
  onChangeText={setEmail}
  placeholder="[email protected]"
  keyboardType="email-address"
  error={emailError}
/>

<FormInput
  label="Password"
  value={password}
  onChangeText={setPassword}
  placeholder="Enter password"
  secureTextEntry={true}
  error={passwordError}
/>

Reusable components can also accept props for maximum length, multiline input, helper text, disabled states, test identifiers, and custom validation rules. For a production component, consider whether capitalization should be configurable rather than inferred from keyboard type.

16. Styling and Improving Input Usability

16.1 Basic Styling Properties

Property Purpose
height / minHeight Controls the field's vertical size.
paddingHorizontal Adds horizontal space inside the field.
fontSize Controls text size.
borderWidth Sets border thickness.
borderColor Sets border color.
borderRadius Rounds the field's corners.
color Sets the entered text color.
backgroundColor Sets the field's background color.
marginBottom Adds space below the field.

16.2 Focused and Error States

A form can use state to indicate when a field is focused or invalid. For example, change the border color when the input receives focus and display a separate message when validation fails.

const [isFocused, setIsFocused] = useState(false);

<TextInput
  value={email}
  onChangeText={setEmail}
  onFocus={() => setIsFocused(true)}
  onBlur={() => setIsFocused(false)}
  style={{
    borderWidth: 1,
    borderColor: isFocused ? '#2457C5' : '#999999',
    borderRadius: 8,
    padding: 12
  }}
/>

16.3 Usability Recommendations

  • Use a clear label for each input.
  • Use placeholders as hints, not as the only label.
  • Keep touch targets and input heights comfortable on mobile devices.
  • Use a suitable keyboard for each kind of information.
  • Provide readable error messages close to the affected field.
  • Ensure adequate contrast between text, placeholders, borders, and backgrounds.
  • Support device text scaling where practical.
  • Test long input, pasted text, and small-screen layouts.

17. Handling Search Input

A search field is a common use of TextInput. It stores the query and lets the application run a search when the user submits it.

function SearchBox({ onSearch }) {
  const [query, setQuery] = useState('');

  function submitSearch() {
    const cleanedQuery = query.trim();

    if (cleanedQuery.length > 0) {
      onSearch(cleanedQuery);
    }
  }

  return (
    <TextInput
      value={query}
      onChangeText={setQuery}
      placeholder="Search items"
      returnKeyType="search"
      onSubmitEditing={submitSearch}
      autoCapitalize="none"
      autoCorrect={false}
      accessibilityLabel="Search items"
    />
  );
}

The parent component supplies the onSearch function. In a larger application, consider debouncing live search requests so the app does not send a network request for every keystroke.

18. Accessibility Best Practices

Accessible input fields help users understand the purpose of each field and interact with forms using different assistive technologies.

  • Provide a meaningful visible label and an appropriate accessibilityLabel.
  • Ensure text and placeholder colors have sufficient contrast.
  • Do not rely on color alone to communicate validation errors.
  • Use clear error messages and identify the field that needs correction.
  • Ensure controls can be reached and used with supported assistive technologies.
  • Use meaningful button labels for actions such as clearing a field or submitting a form.
  • Test with VoiceOver on iOS and TalkBack on Android.
  • Check that larger system text settings do not make important content inaccessible.

19. Common Errors and Troubleshooting

Problem Possible Cause Solution
Input does not update State is not updated in onChangeText. Connect onChangeText to the correct state setter.
Text disappears while typing The controlled value is being reset. Check state updates and ensure value remains a string.
Keyboard shows the wrong layout Incorrect keyboardType or inputMode. Choose the most suitable supported keyboard option.
Password is visible secureTextEntry is missing or false. Set secureTextEntry to true for a single-line password field.
Field accepts too many characters No character limit has been set. Use maxLength and validate important constraints separately.
Validation error appears too early Validation runs before the user has interacted with the field. Track touched or submitted state.
Form submits empty values Submission logic does not validate the data. Validate required fields before continuing.
Keyboard hides the form button Screen layout does not respond well to the keyboard. Review scrolling, keyboard avoidance, and screen layout behavior.
Multiline text is vertically centered Platform-specific text alignment behavior. Try textAlignVertical="top" and test both platforms.
Autofill behaves unexpectedly Autocomplete hints or platform support differ. Review autoComplete and test on supported devices.

19.1 Keeping Controlled Values as Strings

For controlled TextInput fields, initialize text state with an empty string rather than null or undefined. When data comes from an API, convert optional values to a string before passing them to the input.

const [phone, setPhone] = useState('');

<TextInput
  value={phone}
  onChangeText={setPhone}
  keyboardType="phone-pad"
/>

19.2 Handling the Keyboard and Screen Layout

On smaller devices, the software keyboard can cover fields or buttons. Depending on the screen, consider a scrollable layout, suitable safe-area handling, or React Native's KeyboardAvoidingView. Test on real Android and iOS devices because keyboard behavior can differ.

20. Performance and Form Management Best Practices

  • Keep state close to the component that needs it.
  • Use controlled inputs where the application needs validation or programmatic updates.
  • Avoid expensive calculations on every keystroke.
  • Debounce frequent search requests when appropriate.
  • Extract repeated input markup into reusable components.
  • Use functional state updates when the new value depends on previous state.
  • Validate important information on the server as well as in the interface.
  • Keep API submission logic separate from the visual field components.
  • Handle loading, success, and failure states when connecting a form to an API.
  • Do not log sensitive input values such as passwords or authentication codes.

21. Practical Project: Contact Form

Project Objective

Create a contact form in React Native that collects a user's name, email address, and message. The application should validate the input and display a confirmation when the form passes basic validation.

Project Requirements

  • Create three controlled TextInput fields.
  • Use an email keyboard for the email field.
  • Use multiline input for the message.
  • Limit the message length to a reasonable number of characters.
  • Validate required fields.
  • Display relevant error messages.
  • Handle submission using a button.
  • Display a success message only after validation passes.
  • Use consistent input styling and accessible labels.

Suggested Implementation Steps

  1. Create a new React Native screen component.
  2. Import View, Text, TextInput, Pressable, and useState.
  3. Create state variables for name, email, message, and submission status.
  4. Add controlled fields using value and onChangeText.
  5. Implement required-field and email-format validation.
  6. Write a submit handler that prevents invalid submission.
  7. Add clear error messages and success feedback.
  8. Test keyboard behavior, validation, and layout on Android and iOS.

Expected Outcome

The completed form should accept user input, keep the values synchronized with React state, display useful validation messages, and provide clear feedback after a valid submission. Sending the contact details to a real service requires an additional backend or API integration.

22. Practice Exercises

  1. Create a TextInput that accepts a user's full name.
  2. Build an email field using keyboardType and autoCapitalize correctly.
  3. Create a password field using secureTextEntry.
  4. Build a multiline feedback field with a character counter.
  5. Create a form containing name, email, and phone fields.
  6. Show a required-field error after a user attempts to submit an empty form.
  7. Build a search field that submits a non-empty query.
  8. Use a ref to focus an input when a button is pressed.
  9. Create a reusable FormInput component that supports labels and errors.
  10. Build a registration form and test its behavior on Android and iOS.

23. Interview Questions and Answers

Q1. What is TextInput in React Native?

Answer: TextInput is a core component that allows users to enter and edit text using the device keyboard.

Q2. What is the purpose of onChangeText?

Answer: It is a callback that receives the new text value whenever the content of a TextInput changes.

Q3. What is a controlled input?

Answer: A controlled input uses React state as its source of truth through the value prop. The state is updated through a handler such as onChangeText.

Q4. What is the difference between value and defaultValue?

Answer: The value prop controls the current displayed text, while defaultValue specifies the initial text for an input that is not being controlled through value.

Q5. How do you create a password input?

Answer: Use TextInput with secureTextEntry set to true. Additional authentication and data-protection measures are still necessary.

Q6. How can you select the email keyboard?

Answer: Set keyboardType to email-address. For many email fields, autoCapitalize="none" and autoCorrect={false} are also appropriate.

Q7. How do you create a multiline field?

Answer: Set multiline to true and provide suitable height, padding, and alignment. Test its behavior across platforms.

Q8. How can you limit the number of characters?

Answer: Use the maxLength prop. Additional validation may still be needed for application-specific rules.

Q9. What is the purpose of onFocus and onBlur?

Answer: onFocus runs when the field receives focus, while onBlur runs when it loses focus. They can be used for focus styling and validation timing.

Q10. What is onSubmitEditing used for?

Answer: It handles the keyboard submission action, such as submitting a search query. Its behavior can depend on the keyboard and platform.

Q11. Why should forms validate input?

Answer: Validation helps identify missing or incorrectly formatted information before continuing with an operation. The server should also validate important data.

Q12. How can several fields be managed together?

Answer: Use separate state variables or store the field values in an object and update one property at a time while preserving the other properties.

Q13. How can a TextInput be focused programmatically?

Answer: Create a ref using useRef, assign it to the TextInput, and call the focus method when appropriate.

Q14. Why is a placeholder not a complete replacement for a label?

Answer: Placeholder text disappears when users type and may be less accessible. A visible label makes the field's purpose clear throughout interaction.

Q15. What should be considered when using TextInput across Android and iOS?

Answer: Test keyboard behavior, text alignment, autofill, focus handling, and screen layout on both platforms because some properties and behaviors differ.

24. Quick Revision Checklist

  • TextInput collects and edits text entered by the user.
  • Import TextInput from the react-native package.
  • Use useState to manage controlled input values.
  • Use value and onChangeText together for controlled fields.
  • Use placeholder to provide a short hint.
  • Choose a suitable keyboardType for the expected data.
  • Use secureTextEntry for password-style display.
  • Use multiline for longer text.
  • Use maxLength to restrict the number of entered characters.
  • Use onFocus, onBlur, and onSubmitEditing for interaction handling.
  • Validate input before allowing form submission.
  • Keep controlled text values as strings.
  • Use reusable components to maintain consistent form design.
  • Provide accessible labels and useful error messages.
  • Test forms on Android and iOS.
  • Validate important data on the server and protect sensitive information.

25. Conclusion

Managing input fields using TextInput is an essential React Native skill. It enables developers to collect user information, create interactive forms, manage text through state, configure keyboards, handle focus and submission events, and validate information before processing it.

By combining controlled inputs, appropriate keyboard settings, accessible labels, reusable components, clear validation messages, and secure handling of sensitive information, developers can create reliable mobile forms. Practice these concepts by building registration, login, search, and contact screens, and test each form on both Android and iOS.

26. Additional Learning Resources

whatsapp